home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Applications 2004 May / SGI IRIX 6.5 Applications 2004 May.iso / dist / java3d.idb / usr / demos / java / j3d / programs / examples / FourByFour / FourByFour.java.z / FourByFour.java
Encoding:
Java Source  |  2003-08-08  |  31.9 KB  |  880 lines

  1. /*
  2.  *    @(#)FourByFour.java 1.17 02/10/21 13:39:27
  3.  *
  4.  * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *
  10.  * - Redistributions of source code must retain the above copyright
  11.  *   notice, this list of conditions and the following disclaimer.
  12.  *
  13.  * - Redistribution in binary form must reproduce the above copyright
  14.  *   notice, this list of conditions and the following disclaimer in
  15.  *   the documentation and/or other materials provided with the
  16.  *   distribution.
  17.  *
  18.  * Neither the name of Sun Microsystems, Inc. or the names of
  19.  * contributors may be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  *
  22.  * This software is provided "AS IS," without a warranty of any
  23.  * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
  24.  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
  25.  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
  26.  * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
  27.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  28.  * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
  29.  * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
  30.  * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
  31.  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
  32.  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
  33.  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  34.  *
  35.  * You acknowledge that Software is not designed,licensed or intended
  36.  * for use in the design, construction, operation or maintenance of
  37.  * any nuclear facility.
  38.  */
  39.  
  40. import java.applet.Applet;
  41. import java.awt.*;
  42. import java.awt.event.*;
  43. import java.io.*;
  44. import java.net.*;
  45. import javax.media.j3d.*;
  46. import javax.vecmath.*;
  47. import com.sun.j3d.utils.universe.SimpleUniverse;
  48. import com.sun.j3d.utils.applet.MainFrame;
  49.  
  50. /**
  51.  * Class        FourByFour
  52.  *
  53.  * Description: High level class for the game FourByFour
  54.  *
  55.  * Version:     1.2
  56.  *
  57.  */
  58. public class FourByFour extends Applet implements ActionListener {
  59.  
  60.    String host;                    // Host from which this applet came from
  61.    int port;                       // Port number for writing high scores
  62.    Image backbuffer2D;             // Backbuffer image used for 2D double buffering
  63.    int width, height;              // Size of the graphics window in pixels
  64.    int score;                      // Final game score
  65.    int level_weight;               // Weighting factor for skill level 
  66.    int move_weight;                // Weighting factor for number of moves to win
  67.    int time_weight;                // Weighting factor for amount of time it took to win
  68.    int skill_level;                // Skill level, 0 - 4
  69.    Canvas2D canvas2D;              // 2D rendering canvas
  70.    Canvas3D canvas3D;              // 3D rendering canvas
  71.    Board board;                    // Game board object
  72.    Panel b_container;              // Container to hold the buttons
  73.    Panel c_container;              // Container to hold the canvas
  74.    Panel l_container;              // Container to hold the labels
  75.    Panel skill_panel;              // Panel to hold skill levels
  76.    Panel instruct_panel;           // Panel to hold instructions
  77.    Panel winner_panel;             // Panel to hold winner announcement
  78.    Panel high_panel;               // Panel to hold high scores
  79.    Button instruct_button;         // Instructions button
  80.    Button new_button;              // New Game button
  81.    Button skill_button;            // Skill Level button
  82.    Button high_button;             // High Scores button
  83.    Button undo_button;             // Undo Move button
  84.    Label skill_label;              // Label on skill panel
  85.    Label winner_label;             // Label on winner panel
  86.    Label winner_score_label;       // Score label on winner panel
  87.    Label winner_name_label;        // Name label on winner panel
  88.    Label winner_top_label;         // Top 20 label on winner panel
  89.    Label high_label;               // High score label
  90.    Label high_places[];            // Labels to hold places
  91.    Label high_names[];             // Labels to hold names
  92.    Label high_scores[];            // Labels to hold scores 
  93.    TextArea instruct_text;         // TextArea object that holds instructions
  94.    TextArea high_text;             // TextArea object that holds top 20 scores 
  95.    TextField winner_name;          // TextField object that holds winner's name
  96.    Button instruct_return_button;  // Return button for instruction panel
  97.    Button skill_return_button;     // Return button for skill level panel
  98.    Button winner_return_button;    // Return button for winner panel
  99.    Button high_return_button;      // Return button for high scores panel 
  100.    CheckboxGroup group;            // CheckboxGroup object for skill level panel
  101.    InputStream inStream;           // Input stream for reading instructions and high scores 
  102.    OutputStream outStream;         // Output stream for writing high scores
  103.    static boolean appletFlag = true;      // Applet flag
  104.    boolean winner_flag = false;    // Winner flag
  105.    byte text[];                    // Temporary storage area for reading instructions file
  106.    byte outText[];                 // Temporary storage area for writing high scores file
  107.    String textString;              // Storage area for instructions
  108.    String scoresString;            // String used for writing high scores file
  109.    int places[];                   // Storage area for high score places 
  110.    int scores[];                   // Storage area for high score scores
  111.    String names[];                 // Storage area for high score names
  112.    Positions positions;            // Positions object, used to render player positions
  113.  
  114.     private SimpleUniverse universe = null;
  115.  
  116.    /**
  117.     * Initialization
  118.     */
  119.    public void init() {
  120.  
  121.       // Set the port number.
  122.       port = 4111;
  123.  
  124.       // Set the graphics window size.
  125.       width  = 350;
  126.       height = 350;
  127.  
  128.       // Set the weighting factors used for scoring.
  129.       level_weight = 1311;
  130.       move_weight  =  111;
  131.       time_weight  = 1000;
  132.  
  133.       // Create the "base" color for the AWT components.
  134.       setBackground(new Color(200, 200, 200));
  135.  
  136.       // Read the instructions file.
  137.        if (appletFlag) {
  138.  
  139.          // Get the host from which this applet came.
  140.          host = getCodeBase().getHost();
  141.  
  142.          try {
  143.             inStream = new BufferedInputStream
  144.                (new URL(getCodeBase(), "instructions.txt").openStream(), 8192);
  145.             text = new byte[5000];
  146.             int character = inStream.read();
  147.             int count = 0;
  148.             while (character != -1) {
  149.                text[count++] = (byte) character;
  150.                character = inStream.read();
  151.             }
  152.             textString = new String(text);
  153.             inStream.close();
  154.          }
  155.          catch(Exception e) {
  156.             System.out.println("Error: " + e.toString());
  157.          }
  158.       }
  159.       else {
  160.  
  161.          try {
  162.             inStream = new BufferedInputStream
  163.                (new FileInputStream("instructions.txt"));
  164.             text = new byte[5000];
  165.             int character = inStream.read();
  166.             int count = 0;
  167.             while (character != -1) {
  168.                text[count++] = (byte) character;
  169.                character = inStream.read();
  170.             }
  171.             textString = new String(text);
  172.             inStream.close();
  173.          }
  174.          catch(Exception e) {
  175.             System.out.println("Error: " + e.toString());
  176.          }
  177.       }
  178.  
  179.       // Read the high-scores file.
  180.       places = new int[20];
  181.       scores = new int[20];
  182.       names  = new String[20];
  183.       if (appletFlag) {
  184.          try {
  185.             inStream = new BufferedInputStream
  186.                (new URL(getCodeBase(), "scores.txt").openStream(), 8192);
  187.             Reader read = new BufferedReader(new InputStreamReader(inStream));
  188.             StreamTokenizer st = new StreamTokenizer(read);
  189.             st.whitespaceChars(32,44);
  190.             st.eolIsSignificant(false);
  191.  
  192.             int count = 0;
  193.             int token = st.nextToken();
  194.             boolean scoreFlag = true;
  195.             String string;
  196.             while (count<20) {
  197.                places[count] = (int) st.nval;
  198.                string = new String("");
  199.                token = st.nextToken();
  200.                while (token == StreamTokenizer.TT_WORD) {
  201.                   string += st.sval; 
  202.                   string += " ";
  203.                   token = st.nextToken();
  204.                }
  205.                names[count] = string; 
  206.                scores[count] = (int) st.nval;
  207.                token = st.nextToken();
  208.                count++;
  209.             } 
  210.             inStream.close();
  211.          }
  212.          catch(Exception e) {
  213.             System.out.println("Error: " + e.toString());
  214.          }
  215.       }
  216.       else {
  217.          try {
  218.             inStream = new BufferedInputStream
  219.                (new FileInputStream("scores.txt"));
  220.             Reader read = new BufferedReader(new InputStreamReader(inStream));
  221.             StreamTokenizer st = new StreamTokenizer(read);
  222.             st.whitespaceChars(32,44);
  223.             st.eolIsSignificant(false);
  224.  
  225.             int count = 0;
  226.             int token = st.nextToken();
  227.             boolean scoreFlag = true;
  228.             String string;
  229.             while (count<20) {
  230.                places[count] = (int) st.nval;
  231.                string = new String("");
  232.                token = st.nextToken();
  233.                while (token == StreamTokenizer.TT_WORD) {
  234.                   string += st.sval;
  235.                   string += " ";
  236.                   token = st.nextToken();
  237.                }
  238.                names[count] = string;
  239.                scores[count] = (int) st.nval;
  240.                token = st.nextToken();
  241.                count++;
  242.             }
  243.             inStream.close();
  244.          }
  245.          catch(Exception e) {
  246.             System.out.println("Error: " + e.toString());
  247.          }
  248.       }
  249.  
  250.       // The positions object sets up the switch nodes which
  251.       // control the rendering of the player's positions.
  252.       positions = new Positions();
  253.  
  254.       // Create the game board object which is responsible
  255.       // for keeping track of the moves on the game board
  256.       // and determining what move the computer should make.
  257.       board = new Board(this, positions, width, height);
  258.       positions.setBoard(board);
  259.  
  260.       // Create a 2D graphics canvas.
  261.       canvas2D = new Canvas2D(board);
  262.       canvas2D.setSize(width, height);
  263.       canvas2D.setLocation(width+10, 5);
  264.       canvas2D.addMouseListener(canvas2D);
  265.       board.setCanvas(canvas2D);
  266.  
  267.       // Create the 2D backbuffer
  268.       backbuffer2D = createImage(width, height);
  269.       canvas2D.setBuffer(backbuffer2D);
  270.  
  271.       // Create a 3D graphics canvas.
  272.       canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
  273.       canvas3D.setSize(width, height);
  274.       canvas3D.setLocation(5, 5);
  275.  
  276.       // Create the scene branchgroup.
  277.       BranchGroup scene3D = createScene3D();
  278.  
  279.       // Create a universe with the Java3D universe utility.
  280.       universe = new SimpleUniverse(canvas3D);
  281.       universe.addBranchGraph(scene3D);
  282.   
  283.       // Use parallel projection.
  284.       View view = universe.getViewer().getView();
  285.       view.setProjectionPolicy(View.PARALLEL_PROJECTION);
  286.  
  287.       // Set the universe Transform3D object.
  288.       TransformGroup tg = 
  289.          universe.getViewingPlatform().getViewPlatformTransform();
  290.       Transform3D transform = new Transform3D();
  291.       transform.set(65.f, new Vector3f(0.0f, 0.0f, 400.0f));
  292.       tg.setTransform(transform);
  293.  
  294.       // Create the canvas container.
  295.       c_container = new Panel();
  296.       c_container.setSize(720, 360);
  297.       c_container.setLocation(0, 0);
  298.       c_container.setVisible(true);
  299.       c_container.setLayout(null);
  300.       add(c_container);
  301.  
  302.       // Add the 2D and 3D canvases to the container.
  303.       c_container.add(canvas2D);
  304.       c_container.add(canvas3D);
  305.  
  306.       // Turn off the layout manager, widgets will be sized 
  307.       // and positioned explicitly.
  308.       setLayout(null);
  309.  
  310.       // Create the button container.
  311.       b_container = new Panel();
  312.       b_container.setSize(720, 70);
  313.       b_container.setLocation(0, 360);
  314.       b_container.setVisible(true);
  315.       b_container.setLayout(null);
  316.  
  317.       // Create the buttons.
  318.       instruct_button = new Button("Instructions");
  319.       instruct_button.setSize(135, 25);
  320.       instruct_button.setLocation(10, 10);
  321.       instruct_button.setVisible(true);
  322.       instruct_button.addActionListener(this);
  323.  
  324.       new_button = new Button("New Game");
  325.       new_button.setSize(135, 25);
  326.       new_button.setLocation(150, 10);
  327.       new_button.setVisible(true);
  328.       new_button.addActionListener(this);
  329.  
  330.       undo_button = new Button("Undo Move");
  331.       undo_button.setSize(135, 25);
  332.       undo_button.setLocation(290, 10);
  333.       undo_button.setVisible(true);
  334.       undo_button.addActionListener(this);
  335.  
  336.       skill_button = new Button("Skill Level");
  337.       skill_button.setSize(135, 25);
  338.       skill_button.setLocation(430, 10);
  339.       skill_button.setVisible(true);
  340.       skill_button.addActionListener(this);
  341.  
  342.       high_button = new Button("High Scores");
  343.       high_button.setSize(135, 25);
  344.       high_button.setLocation(570, 10);
  345.       high_button.setVisible(true);
  346.       high_button.addActionListener(this);
  347.  
  348.       b_container.add(new_button);
  349.       b_container.add(undo_button);
  350.       b_container.add(skill_button);
  351.       b_container.add(high_button);
  352.       b_container.add(instruct_button);
  353.  
  354.       // Add the button container to the applet.
  355.       add(b_container);
  356.  
  357.       // Create the "Skill Level" dialog box.
  358.       skill_panel = new Panel();
  359.       skill_panel.setSize(400, 300);
  360.       skill_panel.setLocation(200, 20);
  361.       skill_panel.setLayout(null);
  362.  
  363.       skill_label = new Label("Pick your skill level:");
  364.       skill_label.setSize(200, 25);
  365.       skill_label.setLocation(25, 20);
  366.       skill_label.setVisible(true);
  367.       skill_panel.add(skill_label);
  368.  
  369.       group = new CheckboxGroup();
  370.       Checkbox skill_1 = new Checkbox("Babe in the Woods        ", group, false);
  371.       Checkbox skill_2 = new Checkbox("Walk and Chew Gum        ", group, false);
  372.       Checkbox skill_3 = new Checkbox("Jeopardy Contestant      ", group, false);
  373.       Checkbox skill_4 = new Checkbox("Rocket Scientist         ", group, false);
  374.       Checkbox skill_5 = new Checkbox("Be afraid, be very afraid", group, true);
  375.       skill_1.setSize(170, 25);
  376.       skill_1.setLocation(80, 60);
  377.       skill_1.setVisible(true);
  378.       skill_2.setSize(170, 25);
  379.       skill_2.setLocation(80, 100);
  380.       skill_2.setVisible(true);
  381.       skill_3.setSize(170, 25);
  382.       skill_3.setLocation(80, 140);
  383.       skill_3.setVisible(true);
  384.       skill_4.setSize(170, 25);
  385.       skill_4.setLocation(80, 180);
  386.       skill_4.setVisible(true);
  387.       skill_5.setSize(170, 25);
  388.       skill_5.setLocation(80, 220);
  389.       skill_5.setVisible(true);
  390.       skill_return_button = new Button("Return");
  391.       skill_return_button.setSize(120, 25);
  392.       skill_return_button.setLocation(300, 370);
  393.       skill_return_button.setVisible(false);
  394.       skill_return_button.addActionListener(this);
  395.       skill_panel.add(skill_1);
  396.       skill_panel.add(skill_2);
  397.       skill_panel.add(skill_3);
  398.       skill_panel.add(skill_4);
  399.       skill_panel.add(skill_5);
  400.       skill_panel.setVisible(false);
  401.       add(skill_return_button);
  402.       add(skill_panel);
  403.  
  404.       // Create the "Instructions" panel.
  405.       instruct_return_button = new Button("Return");
  406.       instruct_return_button.setLocation(300, 370);
  407.       instruct_return_button.setSize(120, 25);
  408.       instruct_return_button.setVisible(false);
  409.       instruct_return_button.addActionListener(this);
  410.       instruct_text = 
  411.          new TextArea(textString, 100, 200, TextArea.SCROLLBARS_VERTICAL_ONLY);
  412.       instruct_text.setSize(715, 350);
  413.       instruct_text.setLocation(0, 0);
  414.       instruct_text.setVisible(false);
  415.       add(instruct_text);
  416.  
  417.       add(instruct_return_button);
  418.  
  419.       high_panel = new Panel();
  420.       high_panel.setSize(715, 350);
  421.       high_panel.setLocation(0, 0);
  422.       high_panel.setVisible(false);
  423.       high_panel.setLayout(null);
  424.  
  425.       high_label = new Label("High Scores");
  426.       high_label.setLocation(330, 5);
  427.       high_label.setSize(200, 30);
  428.       high_label.setVisible(true);
  429.       high_panel.add(high_label);
  430.  
  431.       high_places = new Label[20];
  432.       high_names  = new Label[20];
  433.       high_scores = new Label[20];
  434.       for (int i=0; i<20; i++) {
  435.          high_places[i] = new Label(Integer.toString(i+1));
  436.          high_places[i].setSize(20, 30);
  437.          high_places[i].setVisible(true);
  438.          high_names[i] = new Label(names[i]);
  439.          high_names[i].setSize(150, 30);
  440.          high_names[i].setVisible(true);
  441.          high_scores[i] = new Label(Integer.toString(scores[i]));
  442.          high_scores[i].setSize(150, 30);
  443.          high_scores[i].setVisible(true);
  444.          if (i<10) {
  445.             high_places[i].setLocation(70, i*30+40);
  446.             high_names[i].setLocation(100, i*30+40);
  447.             high_scores[i].setLocation(260, i*30+40);
  448.          }
  449.          else {
  450.             high_places[i].setLocation(425, (i-10)*30+40);
  451.             high_names[i].setLocation(455, (i-10)*30+40);
  452.             high_scores[i].setLocation(615, (i-10)*30+40);
  453.          }
  454.          high_panel.add(high_places[i]);
  455.          high_panel.add(high_names[i]);
  456.          high_panel.add(high_scores[i]);
  457.       }
  458.       high_return_button = new Button("Return");
  459.       high_return_button.setSize(120, 25);
  460.       high_return_button.setLocation(300, 370);
  461.       high_return_button.setVisible(false);
  462.       high_return_button.addActionListener(this);
  463.       add(high_return_button);
  464.       add(high_panel);
  465.  
  466.       // Create the "Winner" dialog box
  467.       winner_panel = new Panel();
  468.       winner_panel.setLayout(null);
  469.       winner_panel.setSize(600, 500);
  470.       winner_panel.setLocation(0, 0);
  471.       winner_return_button = new Button("Return");
  472.       winner_return_button.setSize(120, 25);
  473.       winner_return_button.setLocation(300, 360);
  474.       winner_return_button.addActionListener(this);
  475.       winner_panel.add(winner_return_button);
  476.       winner_label = new Label("");
  477.       winner_label.setSize(200, 30);
  478.       winner_label.setLocation(270, 110);
  479.       winner_score_label = new Label("");
  480.       winner_score_label.setSize(200, 30);
  481.       winner_top_label = new Label("You have a score in the top 20.");
  482.       winner_top_label.setSize(200, 25);
  483.       winner_top_label.setLocation(260, 185);
  484.       winner_top_label.setVisible(false); winner_name_label = new Label("Enter your name here:");
  485.       winner_name_label.setSize(150, 25);
  486.       winner_name_label.setLocation(260, 210);
  487.       winner_name_label.setVisible(false);
  488.       winner_name = new TextField("");
  489.       winner_name.setSize(200, 30);
  490.       winner_name.setLocation(260, 240);
  491.       winner_name.setVisible(false);
  492.       winner_panel.add(winner_label);
  493.       winner_panel.add(winner_score_label);
  494.       winner_panel.add(winner_top_label);
  495.       winner_panel.add(winner_name_label);
  496.       winner_panel.add(winner_name);
  497.       winner_panel.setVisible(false);
  498.       add(winner_panel);
  499.    }
  500.  
  501.     public void destroy() {
  502.     universe.cleanup();
  503.     }
  504.  
  505.    /**
  506.     *  Create the scenegraph for the 3D view.
  507.     */
  508.    public BranchGroup createScene3D() {
  509.  
  510.       // Define colors
  511.       Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
  512.       Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
  513.       Color3f red   = new Color3f(0.80f, 0.20f, 0.2f);
  514.       Color3f ambient = new Color3f(0.25f, 0.25f, 0.25f);
  515.       Color3f diffuse = new Color3f(0.7f, 0.7f, 0.7f);
  516.       Color3f specular = new Color3f(0.9f, 0.9f, 0.9f);
  517.       Color3f ambientRed = new Color3f(0.2f, 0.05f, 0.0f);
  518.       Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
  519.  
  520.       // Create the branch group
  521.       BranchGroup branchGroup = new BranchGroup();
  522.  
  523.       // Create the bounding leaf node
  524.       BoundingSphere bounds =
  525.          new BoundingSphere(new Point3d(0.0,0.0,0.0), 1000.0);
  526.       BoundingLeaf boundingLeaf = new BoundingLeaf(bounds);
  527.       branchGroup.addChild(boundingLeaf);
  528.  
  529.       // Create the background
  530.       Background bg = new Background(bgColor);
  531.       bg.setApplicationBounds(bounds);
  532.       branchGroup.addChild(bg);
  533.  
  534.       // Create the ambient light
  535.       AmbientLight ambLight = new AmbientLight(white);
  536.       ambLight.setInfluencingBounds(bounds);
  537.       branchGroup.addChild(ambLight);
  538.  
  539.       // Create the directional light
  540.       Vector3f dir = new Vector3f(-1.0f, -1.0f, -1.0f);
  541.       DirectionalLight dirLight = new DirectionalLight(white, dir);
  542.       dirLight.setInfluencingBounds(bounds);
  543.       branchGroup.addChild(dirLight);
  544.  
  545.       // Create the pole appearance
  546.       Material poleMaterial =
  547.          new Material(ambient, black, diffuse, specular, 110.f);
  548.       poleMaterial.setLightingEnable(true);
  549.       Appearance poleAppearance = new Appearance();
  550.       poleAppearance.setMaterial(poleMaterial);
  551.  
  552.       // Create the transform group node
  553.       TransformGroup transformGroup = new TransformGroup();
  554.       transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
  555.       transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  556.       branchGroup.addChild(transformGroup);
  557.  
  558.       // Create the poles
  559.       Poles poles = new Poles(poleAppearance);
  560.       transformGroup.addChild(poles.getChild());
  561.  
  562.       // Add the position markers to the transform group
  563.       transformGroup.addChild(positions.getChild());
  564.  
  565.       // Let the positions object know about the transform group
  566.       positions.setTransformGroup(transformGroup);
  567.  
  568.       // Create the mouse pick and drag behavior node
  569.       PickDragBehavior behavior = new PickDragBehavior(canvas2D, canvas3D, positions, 
  570.                                                        branchGroup, transformGroup);
  571.       behavior.setSchedulingBounds(bounds);
  572.       transformGroup.addChild(behavior);
  573.  
  574.       return branchGroup;
  575.    }
  576.  
  577.    public void actionPerformed (ActionEvent event) {
  578.  
  579.       Object target = event.getSource();
  580.  
  581.       // Process the button events.
  582.       if (target == skill_return_button) {
  583.          skill_panel.setVisible(false);
  584.          skill_return_button.setVisible(false);
  585.          c_container.setVisible(true);
  586.          b_container.setVisible(true);
  587.          newGame();
  588.       }
  589.       else if (target == winner_return_button) {
  590.          if (winner_flag) {
  591.             String name = winner_name.getText();
  592.             String tmp_name = new String("");
  593.             int tmp_score = 0;
  594.             boolean insert_flag = false;
  595.             winner_flag = false;
  596.             for (int i=0; i<20; i++) {
  597.                if (insert_flag) {
  598.                   name = names[i];
  599.                   score = scores[i];
  600.                   names[i] = tmp_name;
  601.                   scores[i] = tmp_score;
  602.                   tmp_name = name;
  603.                   tmp_score = score;
  604.                }
  605.                if (!insert_flag && score > scores[i]) {
  606.                   tmp_name = names[i];
  607.                   tmp_score = scores[i];
  608.                   scores[i] = score;
  609.                   names[i] = name;
  610.                   insert_flag = true;
  611.                }
  612.                high_names[i].setText(names[i]);
  613.                high_scores[i].setText(Integer.toString(scores[i]));
  614.             }
  615.             scoresString = new String("");
  616.             int place;
  617.             for (int i=0; i<20; i++) {
  618.                place = (int) places[i];
  619.                scoresString += Integer.toString(place);
  620.                scoresString += "\t";
  621.                scoresString += names[i];
  622.                scoresString += "   ";
  623.                scoresString += Integer.toString(scores[i]);
  624.                scoresString += "\n";
  625.             }
  626.  
  627.             if (appletFlag) {
  628.                // Use this section of code when writing the high
  629.                // scores file back to a server. Requires the use
  630.                // of a deamon on the server to receive the socket 
  631.                // connection.
  632.                //
  633.                // Create the output stream.
  634.                // try {
  635.                //    Socket socket = new Socket(host, port);
  636.                //    outStream = new BufferedOutputStream
  637.                //       (socket.getOutputStream(), 8192);
  638.                // }
  639.                // catch(IOException ioe) {
  640.                //    System.out.println("Error: " + ioe.toString());
  641.                // }
  642.                // System.out.println("Output stream opened");
  643.                //
  644.                // Write the scores to the file back on the server.
  645.                // outText = scoresString.getBytes();
  646.                // try {
  647.                //    outStream.write(outText);
  648.                //    outStream.flush();
  649.                //    outStream.close();
  650.                //    outStream = null;
  651.                // }
  652.                // catch (IOException ioe) {
  653.                //    System.out.println("Error: " + ioe.toString());
  654.                // }
  655.                // System.out.println("Output stream written");
  656.  
  657.           try {
  658.         OutputStreamWriter outFile =
  659.           new OutputStreamWriter(new FileOutputStream("scores.txt"));
  660.         outFile.write(scoresString);
  661.         outFile.flush();
  662.         outFile.close();
  663.         outFile = null;
  664.           }
  665.           catch (IOException ioe) {
  666.         System.out.println("Error: " + ioe.toString());
  667.           }
  668.           catch (Exception e) {
  669.         System.out.println("Error: " + e.toString());
  670.           }
  671.         }
  672.            else {
  673.  
  674.                try {
  675.                   OutputStreamWriter outFile = 
  676.                         new OutputStreamWriter(new FileOutputStream("scores.txt"));
  677.                      outFile.write(scoresString);
  678.                      outFile.flush();
  679.                      outFile.close();
  680.                      outFile = null;
  681.                }
  682.                catch (IOException ioe) {
  683.                   System.out.println("Error: " + ioe.toString());
  684.                }
  685.             }
  686.          }
  687.          winner_panel.setVisible(false);
  688.          winner_return_button.setVisible(false);
  689.          winner_label.setVisible(false);
  690.          winner_score_label.setVisible(false);
  691.          winner_name_label.setVisible(false);
  692.          winner_top_label.setVisible(false);
  693.          winner_name.setVisible(false);
  694.          c_container.setVisible(true);
  695.          b_container.setVisible(true);
  696.       }
  697.       else if (target == high_return_button) {
  698.          high_return_button.setVisible(false);
  699.          high_panel.setVisible(false);
  700.          c_container.setVisible(true);
  701.          b_container.setVisible(true);
  702.       }
  703.       else if (target == instruct_return_button) {
  704.          instruct_text.setVisible(false);
  705.          instruct_return_button.setVisible(false);
  706.          instruct_text.repaint();
  707.          c_container.setVisible(true);
  708.          b_container.setVisible(true);
  709.       }
  710.       else if (target == undo_button) {
  711.          board.undo_move();
  712.          canvas2D.repaint();
  713.       }
  714.       else if (target == instruct_button) {
  715.          c_container.setVisible(false);
  716.          b_container.setVisible(false);
  717.          instruct_text.setVisible(true);
  718.          instruct_return_button.setVisible(true);
  719.       }
  720.       else if (target == new_button) {
  721.          newGame();
  722.       }
  723.       else if (target == skill_button) {
  724.          c_container.setVisible(false);
  725.          b_container.setVisible(false);
  726.          skill_panel.setVisible(true);
  727.          skill_return_button.setVisible(true);
  728.       }
  729.       else if (target == high_button) {
  730.          // Read the high scores file.
  731.          if (appletFlag) {
  732.             try {
  733.                inStream = new BufferedInputStream
  734.                   (new URL(getCodeBase(), "scores.txt").openStream(), 8192);
  735.                Reader read = new BufferedReader(new InputStreamReader(inStream));
  736.                StreamTokenizer st = new StreamTokenizer(read);
  737.                st.whitespaceChars(32,44);
  738.                st.eolIsSignificant(false);
  739.  
  740.                int count = 0;
  741.                int token = st.nextToken();
  742.                boolean scoreFlag = true;
  743.                String string;
  744.                while (count<20) {
  745.                   places[count] = (int) st.nval;
  746.                   string = new String("");
  747.                   token = st.nextToken();
  748.                   while (token == StreamTokenizer.TT_WORD) {
  749.                      string += st.sval;
  750.                      string += " ";
  751.                      token = st.nextToken();
  752.                   }
  753.                   names[count] = string;
  754.                   scores[count] = (int) st.nval;
  755.                   token = st.nextToken();
  756.                   count++;
  757.                }
  758.                inStream.close();
  759.             }
  760.             catch(Exception ioe) {
  761.                System.out.println("Error: " + ioe.toString());
  762.             }
  763.          }
  764.          else {
  765.             try {
  766.                inStream = new BufferedInputStream
  767.                   (new FileInputStream("scores.txt"));
  768.                Reader read = new BufferedReader(new InputStreamReader(inStream));
  769.                StreamTokenizer st = new StreamTokenizer(read);
  770.                st.whitespaceChars(32,44);
  771.                st.eolIsSignificant(false);
  772.  
  773.                int count = 0;
  774.                int token = st.nextToken();
  775.                boolean scoreFlag = true;
  776.                String string;
  777.                while (count<20) {
  778.                   places[count] = (int) st.nval;
  779.                   string = new String("");
  780.                   token = st.nextToken();
  781.                   while (token == StreamTokenizer.TT_WORD) {
  782.                      string += st.sval;
  783.                      string += " ";
  784.                      token = st.nextToken();
  785.                   }
  786.                   names[count] = string;
  787.                   scores[count] = (int) st.nval;
  788.                   token = st.nextToken();
  789.                   count++;
  790.                }
  791.                inStream.close();
  792.             }
  793.             catch(Exception ioe) {
  794.                System.out.println("Error: " + ioe.toString());
  795.             }
  796.          }
  797.          c_container.setVisible(false);
  798.          b_container.setVisible(false);
  799.          high_panel.setVisible(true);
  800.          high_return_button.setVisible(true);
  801.       }
  802.  
  803.       Checkbox box = group.getSelectedCheckbox(); 
  804.       String label = box.getLabel();
  805.       if (label.equals("Babe in the Woods        ")) {
  806.          board.set_skill_level(0);
  807.       }
  808.       else if (label.equals("Walk and Chew Gum        ")) {
  809.          board.set_skill_level(1);
  810.       }
  811.       else if (label.equals("Jeopardy Contestant      ")) {
  812.          board.set_skill_level(2);
  813.       }
  814.       else if (label.equals("Rocket Scientist         ")) {
  815.          board.set_skill_level(3);
  816.       }
  817.       else if (label.equals("Be afraid, be very afraid")) {
  818.          board.set_skill_level(4);
  819.       }
  820.    }
  821.  
  822.    public void newGame() {
  823.       board.newGame();         
  824.       canvas2D.repaint();
  825.    }
  826.  
  827.    public void start() {
  828.       if (appletFlag) showStatus("FourByFour");
  829.    }
  830.  
  831.    public void winner(int player, int level, int nmoves, long time) {
  832.  
  833.       if (player == 1) { 
  834.          score = level *  level_weight + 
  835.                  (66 - nmoves) * move_weight -
  836.                  (int) Math.min(time * time_weight, 5000);
  837.          winner_label.setText("Game over, you win!");
  838.          winner_label.setLocation(290, 90);
  839.          winner_score_label.setText("Score = " + score);
  840.          winner_score_label.setVisible(true);
  841.          winner_score_label.setLocation(315, 120);
  842.          if (score > scores[19]) {
  843.             winner_name_label.setVisible(true);
  844.             winner_top_label.setVisible(true);
  845.             winner_name.setVisible(true);
  846.             winner_flag = true;
  847.          }
  848.       }
  849.       else {
  850.          winner_label.setText("Game over, the computer wins!");
  851.          winner_label.setLocation(250, 150);
  852.       }
  853.       c_container.setVisible(false);
  854.       b_container.setVisible(false);
  855.       winner_panel.setVisible(true);
  856.       winner_label.setVisible(true);
  857.       winner_return_button.setVisible(true);
  858.       repaint();
  859.    }
  860.  
  861.    /**
  862.     *  Inner class used to "kill" the window when running as
  863.     *  an application.
  864.     */
  865.    static class killAdapter extends WindowAdapter {
  866.       public void windowClosing(WindowEvent event) {
  867.          System.exit(0);
  868.       }
  869.    }
  870.  
  871.   /**
  872.    *  Main method, only used when running as an application.
  873.    */
  874.   public static void main(String[] args) {
  875.     FourByFour.appletFlag = false;
  876.     new MainFrame(new FourByFour(), 730, 450);
  877.   }
  878.   
  879. }
  880.